﻿// -----------------------------------------------------------------------
// <copyright file="SPPropertyBagHelper.cs" company="Microsoft">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace LifeInSharePoint.EUCookie.Utilities
{
    using System.Collections.Generic;

    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Administration;

    /// <summary>
    /// The sp property bag helper.
    /// </summary>
    public static class SPPropertyBagHelper
    {
        /// <summary>
        /// Simply adds a key/value pair to the SPWeb AllProperties Hashtable and the
        /// Deprecated SPWeb Property bag without updating
        /// </summary>
        /// <param name="web">
        /// The web.
        /// </param>
        /// <param name="key">
        /// The key.
        /// </param>
        /// <param name="value">
        /// The value.
        /// </param>
        public static void AddProperty(this SPWeb web, string key, string value)
        {
            web.Properties[key] = value;
            web.AllProperties[key] = value;
        }

        /// <summary>
        /// Simply removes the property with the given key from the SPWeb AllProperties
        /// hashtable and the deprecated SPWeb property bag without updating
        /// </summary>
        /// <param name="web">
        /// The web.
        /// </param>
        /// <param name="key">
        /// The key.
        /// </param>
        public static void RemoveProperty(this SPWeb web, string key)
        {
            web.AllProperties.Remove(key);
            web.Properties[key] = null;
        }

        /// <summary>
        /// Adds the given key/value pair to both the SPWeb AllProperties Hashtable and
        /// the deprecated SPWeb Property Bag and Updates both the Property Bag and the SPWeb.
        /// This method ensures the operation is done with System permissions.
        /// </summary>
        /// <param name="web">
        /// The web.
        /// </param>
        /// <param name="key">
        /// The key.
        /// </param>
        /// <param name="value">
        /// The value.
        /// </param>
        public static void AddPropertyAndUpdate(this SPWeb web, string key, string value)
        {
            var properties = new Dictionary<string, string>(1);
            properties.Add(key, value);
            AddPropertiesAndUpdate(web, properties);
        }

        /// <summary>
        /// Adds the given key/value pairs to both the SPWeb AllProperties Hashtable and
        /// the deprecated SPWeb Property Bag and Updates both the Property Bag and the SPWeb.
        /// This method ensures the operation is done with System permissions.
        /// </summary>
        /// <param name="web">
        /// The web.
        /// </param>
        /// <param name="properties">
        /// The properties.
        /// </param>
        public static void AddPropertiesAndUpdate(this SPWeb web, IDictionary<string, string> properties)
        {
            SPImpersonationHelper.DoUnsafeUpdateAsSystemUser(web, delegate(SPWeb systemWeb)
            {
                foreach (var pair in properties)
                {
                    AddProperty(systemWeb, pair.Key, pair.Value);
                }

                systemWeb.Update();
                systemWeb.Properties.Update();
            });
        }

        /// <summary>
        /// Removes the property with the given key from both the SPWeb AllProperties
        /// hashtable and the deprecated SPWeb Property Bag and updates both the Property Bag
        /// and the SPWeb.  This method ensures the operation is done with System permissions.
        /// </summary>
        /// <param name="web">
        /// The web.
        /// </param>
        /// <param name="key">
        /// The key.
        /// </param>
        public static void RemovePropertyAndUpdate(this SPWeb web, string key)
        {
            RemovePropertiesAndUpdate(web, key);
        }

        /// <summary>
        /// Removes the properties with the given keys from both the SPWeb AllProperties
        /// hashtable and the deprecated SPWeb Property Bag and updates both the Property Bag
        /// and the SPWeb.  This method ensures the operation is done with System permissions.
        /// </summary>
        /// <param name="web">
        /// The web.
        /// </param>
        /// <param name="keys">
        /// The keys.
        /// </param>
        public static void RemovePropertiesAndUpdate(this SPWeb web, params string[] keys)
        {
            SPImpersonationHelper.DoUnsafeUpdateAsSystemUser(web, delegate(SPWeb systemWeb)
            {
                foreach (var key in keys)
                {
                    RemoveProperty(systemWeb, key);
                }

                systemWeb.Update();
                systemWeb.Properties.Update();
            });
        }

        /// <summary>
        /// Safely gets a property value from the SPWeb Property Bag
        /// </summary>
        /// <param name="web">
        /// The web.
        /// </param>
        /// <param name="key">
        /// The key.
        /// </param>
        /// <returns>
        /// The <see cref="string"/>.
        /// </returns>
        public static string GetPropertyValue(this SPWeb web, string key)
        {
            if (web.AllProperties.ContainsKey(key))
                return web.AllProperties[key].ToString();

            return null;
        }

        /// <summary>
        /// Reads a property value from the Farms property bag with elevated priveleges
        /// </summary>
        /// <param name="key">
        /// The key.
        /// </param>
        /// <returns>
        /// The <see cref="string"/>.
        /// </returns>
        public static string GetFarmProperty(string key)
        {
            return GetFarmProperty<string>(key);
        }

        /// <summary>
        /// Reads a property value from the Farms property bag with elevated priveleges
        /// </summary>
        /// <param name="key">
        /// The key.
        /// </param>
        /// <typeparam name="T">
        /// T can be a string, DateTime, or an int
        /// </typeparam>
        /// <returns>
        /// The <see cref="T"/>.
        /// </returns>
        public static T GetFarmProperty<T>(string key)
        {
            T value = default(T);
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                var farmProperties = SPFarm.Local.Properties;
                if (farmProperties.ContainsKey(key))
                    value = (T)farmProperties[key];
            });
            return value;
        }
    }
}
